Track viewable for GdkWindow
authorAlexander Larsson <alexl@redhat.com>
Sat, 18 Jul 2009 18:29:50 +0000 (20:29 +0200)
committerAlexander Larsson <alexl@redhat.com>
Sat, 18 Jul 2009 21:11:54 +0000 (23:11 +0200)
gdk/directfb/gdkwindow-directfb.c
gdk/gdkevents.c
gdk/gdkinternals.h
gdk/gdkwindow.c
gdk/quartz/gdkwindow-quartz.c
gdk/win32/gdkwindow-win32.c
gdk/x11/gdkwindow-x11.c

index 7f82a6d083b8c67cd1cef2d3f8553f98f76f6993..b7795f8ea48582c83f77b7036947809b7d2a939b 100644 (file)
@@ -313,6 +313,7 @@ _gdk_windowing_window_init (void)
   private->window_type = GDK_WINDOW_ROOT;
   private->state       = 0;
   private->children    = NULL;
+  private->viewable = TRUE;
 //  impl->drawable.paint_region   = NULL;
   impl->gdkWindow      = _gdk_parent_root;
   impl->window           = NULL;
@@ -2501,6 +2502,7 @@ gdk_window_foreign_new_for_display (GdkDisplay* display,GdkNativeWindow anid)
     private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
     private->parent = parent_private;
     private->window_type = GDK_WINDOW_TOPLEVEL;
+    private->viewable = TRUE;
     impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
 
     impl->drawable.wrapper = GDK_DRAWABLE (window);
index 3af4195cc93b6e28159eb179faa89eec283cda80..90e16d7bd85e320fde7e7da66ac9ecca2c3b7e78 100644 (file)
@@ -1266,6 +1266,9 @@ gdk_synthesize_window_state (GdkWindow     *window,
   
   ((GdkWindowObject*) window)->state = temp_event.window_state.new_window_state;
 
+  if (temp_event.window_state.changed_mask & GDK_WINDOW_STATE_WITHDRAWN)
+    _gdk_window_update_viewable (window);
+
   /* We only really send the event to toplevels, since
    * all the window states don't apply to non-toplevels.
    * Non-toplevels do use the GDK_WINDOW_STATE_WITHDRAWN flag
index 6d1a4d061329fe4b118dbc5c1c4baac95ea6dd6b..ec29042b75c7b63a7de94014a1f16f58e439e6c7 100644 (file)
@@ -260,6 +260,7 @@ struct _GdkWindowObject
   guint effective_visibility : 2;
   guint visibility : 2; /* The visibility wrt the toplevel (i.e. based on clip_region) */
   guint native_visibility : 2; /* the native visibility of a impl windows */
+  guint viewable : 1; /* mapped and all parents mapped */
 
   guint num_offscreen_children;
   GdkWindowPaint *implicit_paint;
@@ -385,6 +386,7 @@ void       _gdk_window_destroy           (GdkWindow      *window,
                                           gboolean        foreign_destroy);
 void       _gdk_window_clear_update_area (GdkWindow      *window);
 void       _gdk_window_update_size       (GdkWindow      *window);
+void       _gdk_window_update_viewable   (GdkWindow      *window);
 
 void       _gdk_window_process_updates_recurse (GdkWindow *window,
                                                 GdkRegion *expose_region);
index 4bcbfbc90fb29f6c0ed67173e886c068c654bfa6..c8778c31998405518d41fbdee088dc3fe1caa302 100644 (file)
@@ -1479,6 +1479,8 @@ gdk_window_reparent (GdkWindow *window,
       apply_redirect_to_children (private, private->redirect);
     }
 
+  _gdk_window_update_viewable (window);
+
   recompute_visible_regions (private, TRUE, FALSE);
   if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
     recompute_visible_regions (old_parent, FALSE, TRUE);
@@ -2208,25 +2210,13 @@ gboolean
 gdk_window_is_viewable (GdkWindow *window)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkScreen *screen;
-  GdkWindow *root_window;
 
   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
 
-  screen = gdk_drawable_get_screen (window);
-  root_window = gdk_screen_get_root_window (screen);
-
-  while (private &&
-        (private != (GdkWindowObject *)root_window) &&
-        (private->window_type != GDK_WINDOW_FOREIGN))
-    {
-      if (GDK_WINDOW_DESTROYED (private) || !GDK_WINDOW_IS_MAPPED (private))
-       return FALSE;
-
-      private = (GdkWindowObject *)private->parent;
-    }
+  if (private->destroyed)
+    return FALSE;
 
-  return TRUE;
+  return private->viewable;
 }
 
 /**
@@ -5774,6 +5764,45 @@ show_all_visible_impls (GdkWindowObject *private, gboolean already_mapped)
     GDK_WINDOW_IMPL_GET_IFACE (private->impl)->show ((GdkWindow *)private, already_mapped);
 }
 
+static void
+set_viewable (GdkWindowObject *w,
+             gboolean val)
+{
+  GdkWindowObject *child;
+  GList *l;
+
+  w->viewable = val;
+
+  for (l = w->children; l != NULL; l = l->next)
+    {
+      child = l->data;
+
+      if (GDK_WINDOW_IS_MAPPED (child) &&
+         child->window_type != GDK_WINDOW_FOREIGN)
+       set_viewable (child, val);
+    }
+}
+
+void
+_gdk_window_update_viewable (GdkWindow *window)
+{
+  GdkWindowObject *priv = (GdkWindowObject *)window;
+  gboolean viewable;
+
+  if (priv->window_type == GDK_WINDOW_FOREIGN ||
+      priv->window_type == GDK_WINDOW_ROOT)
+    viewable = TRUE;
+  else if (priv->parent == NULL ||
+          priv->parent->window_type == GDK_WINDOW_ROOT ||
+          priv->parent->viewable)
+    viewable = GDK_WINDOW_IS_MAPPED (priv);
+  else
+    viewable = FALSE;
+
+  if (priv->viewable != viewable)
+    set_viewable (priv, viewable);
+}
+
 static void
 gdk_window_show_internal (GdkWindow *window, gboolean raise)
 {
@@ -5804,6 +5833,8 @@ gdk_window_show_internal (GdkWindow *window, gboolean raise)
       private->state = 0;
     }
 
+  _gdk_window_update_viewable (window);
+
   if (gdk_window_is_viewable (window))
     show_all_visible_impls (private, was_mapped);
 
@@ -6106,6 +6137,8 @@ gdk_window_hide (GdkWindow *window)
       private->state = GDK_WINDOW_STATE_WITHDRAWN;
     }
 
+  _gdk_window_update_viewable (window);
+
   if (was_viewable)
     hide_all_visible_impls (private);
 
index 283cda18ffa2ce97bca1187b51797fed976a03fa..cbc80a7e732818639360c26a08f08d0a743f5414 100644 (file)
@@ -969,6 +969,7 @@ _gdk_windowing_window_init (void)
   private->state = 0; /* We don't want GDK_WINDOW_STATE_WITHDRAWN here */
   private->window_type = GDK_WINDOW_ROOT;
   private->depth = 24;
+  private->viewable = TRUE;
 
   drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (private->impl);
   
index cf2708668529c030d2c7a4a66a85a3745cf9d1d0..461f61786fe052d6cb1b98c06ba3a95f2f75e375 100644 (file)
@@ -283,6 +283,7 @@ _gdk_windowing_window_init (GdkScreen *screen)
   private->abs_y = 0;
   private->width = GetSystemMetrics (SM_CXSCREEN);
   private->height = GetSystemMetrics (SM_CYSCREEN);
+  private->viewable = TRUE;
 
   gdk_win32_handle_table_insert ((HANDLE *) &draw_impl->handle, _gdk_root);
 
@@ -758,6 +759,7 @@ gdk_window_foreign_new_for_display (GdkDisplay      *display,
   else
     private->state &= (~GDK_WINDOW_STATE_ABOVE);
   private->state &= (~GDK_WINDOW_STATE_BELOW);
+  private->viewable = TRUE;
 
   private->depth = gdk_visual_get_system ()->depth;
 
index 9cd453b1ee27a7264f35a6ff062cd88730651410..b6e19c3a542721b209899c01e4b049d07b99c2dd 100644 (file)
@@ -450,6 +450,7 @@ _gdk_windowing_window_init (GdkScreen * screen)
   private->abs_y = 0;
   private->width = WidthOfScreen (screen_x11->xscreen);
   private->height = HeightOfScreen (screen_x11->xscreen);
+  private->viewable = TRUE;
   _gdk_window_update_size (screen_x11->root_window);
   
   _gdk_xid_table_insert (screen_x11->display,
@@ -936,6 +937,7 @@ gdk_window_foreign_new_for_display (GdkDisplay     *display,
     private->state = GDK_WINDOW_STATE_WITHDRAWN;
   else
     private->state = 0;
+  private->viewable = TRUE;
 
   private->depth = attrs.depth;
   
@@ -944,7 +946,7 @@ gdk_window_foreign_new_for_display (GdkDisplay     *display,
 
   /* Update the clip region, etc */
   _gdk_window_update_size (window);
-  
+
   return window;
 }